{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Part 01 - The Basic Tools of Private Deep Learning.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7ovaNpgEXZBr",
        "colab_type": "text"
      },
      "source": [
        "##Tutoriel: Les outils de base de Private Deep Learning\n",
        "\n",
        "Bienvenue dans le didacticiel d'introduction de PySyft pour un apprentissage approfondi décentralisé préservant la confidentialité. Cette série de cahiers est un guide étape par étape pour vous familiariser avec les nouveaux outils et techniques nécessaires pour effectuer un apprentissage approfondi sur des données / modèles secrets / privés sans les centraliser sous une seule autorité.\n",
        "\n",
        "**Portée**: notez que nous ne parlerons pas seulement de la manière de décentraliser / crypter les données, mais de la façon dont PySyft peut être utilisé pour aider à décentraliser l'ensemble de l'écosystème autour des données, y compris les bases de données où les données sont stockées et interrogées, et les modèles neuronaux qui sont utilisés pour extraire des informations des données. À mesure que de nouvelles extensions de PySyft sont créées, ces blocs-notes seront étendus avec de nouveaux didacticiels pour expliquer la nouvelle fonctionnalité.\n",
        "\n",
        "Auteurs:\n",
        "\n",
        "* Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
        "\n",
        "##Contour:\n",
        "\n",
        "* Partie 1: Les outils de base de Private Deep Learning\n",
        "\n",
        "##Pourquoi suivre ce didacticiel?\n",
        "\n",
        "1) Un avantage de carrière compétitif - Au cours des 20 dernières années, la révolution numérique a rendu les données de plus en plus accessibles en quantités toujours plus importantes à mesure que les processus analogiques se sont numérisés. Cependant, avec la nouvelle réglementation telle que le GDPR, les entreprises sont sous pression pour avoir moins de liberté dans la façon dont elles utilisent - et plus important encore dans la façon dont elles analysent - les informations personnelles. Bottom Line: Les Data Scientists n'auront pas accès à autant de données avec des outils \"old school\", mais en apprenant les outils du Private Deep Learning, VOUS pouvez être en avance sur cette courbe et avoir un avantage compétitif dans votre carrière.\n",
        "\n",
        "2) Opportunités entrepreneuriales - Il existe toute une série de problèmes dans la société que le Deep Learning peut résoudre, mais bon nombre des plus importants n'ont pas été explorés car cela nécessiterait l'accès à des informations incroyablement sensibles sur les personnes (pensez à utiliser le Deep Learning pour aider les gens avec des problèmes mentaux ou relationnels!). Ainsi, l'apprentissage Private Deep Learning ouvre pour vous une multitude de nouvelles opportunités de démarrage qui n'étaient pas disponibles auparavant pour d'autres sans ces outils.\n",
        "\n",
        "3) Bien social - Le Deep Learning peut être utilisé pour résoudre une grande variété de problèmes dans le monde réel, mais le Deep Learning sur les informations personnelles est le Deep Learning sur les gens, pour les gens. Apprendre à faire du Deep Learning sur des données que vous ne possédez pas représente plus qu'une carrière ou une opportunité entrepreneuriale, c'est l'occasion d'aider à résoudre certains des problèmes les plus personnels et les plus importants de la vie des gens - et de le faire à grande échelle.\n",
        "\n",
        "\n",
        "##Comment obtenir un crédit supplémentaire?\n",
        "\n",
        "* Star PySyft sur GitHub! - https://github.com/OpenMined/PySyft\n",
        "* Faites une vidéo Youtube enseignant ce cahier!\n",
        "\n",
        "##Partie -1: Conditions préalables\n",
        "\n",
        "* Connaissez PyTorch - sinon, suivez le cours http://fast.ai et revenez\n",
        "* Lisez le document cadre PySyft https://arxiv.org/pdf/1811.04017.pdf! Cela vous donnera un aperçu complet de la façon dont PySyft est construit, ce qui aidera les choses à avoir plus de sens.\n",
        "\n",
        "##Partie 0: \n",
        "Pour commencer, vous devrez vous assurer que les bonnes choses sont installées. Pour ce faire, rendez-vous sur le fichier Readme de PySyft et suivez les instructions de configuration. TLDR pour la plupart des gens est.\n",
        "\n",
        "* Installez Python 3.6 ou supérieur\n",
        "* Installez PyTorch 1.3\n",
        "* Clone PySyft (git clone https://github.com/OpenMined/PySyft.git)\n",
        "* cd PySyft\n",
        "* pip install -r pip-dep/requirements.txt\n",
        "* pip install -r pip-dep/requirements_udacity.txt\n",
        "* python setup.py install udacity\n",
        "* python setup.py test\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "Si une partie de cela ne fonctionne pas pour vous (ou l'un des tests échoue) - consultez d'abord le fichier [README](https://github.com/OpenMined/PySyft) pour l'aide à l'installation, puis ouvrez un problème GitHub ou envoyez une requête ping au canal #beginner dans notre mou! [slack.openmined.org](slack.openmined.org)\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jTYZt5tmcPHE",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Run this cell to see if things work\n",
        "import sys\n",
        "\n",
        "import torch\n",
        "from torch.nn import Parameter\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "\n",
        "import syft as sy\n",
        "hook = sy.TorchHook(torch)\n",
        "\n",
        "torch.tensor([1,2,3,4,5])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uTR3KrpBcYz5",
        "colab_type": "text"
      },
      "source": [
        "Si cette cellule est exécutée, alors c'est parti pour les courses! Faisons cela!\n",
        "\n",
        "##Partie 1 - Les outils de base de la science des données privée et décentralisée\n",
        "\n",
        "Donc - la première question que vous vous posez peut-être est la suivante: comment diable formons-nous un modèle sur des données auxquelles nous n'avons pas accès?\n",
        "\n",
        "Eh bien, la réponse est étonnamment simple. Si vous avez l'habitude de travailler dans PyTorch, alors vous avez l'habitude de travailler avec des objets torche.Tensor comme ceux-ci!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QB4fISt_dHqR",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = torch.tensor([1,2,3,4,5])\n",
        "y = x + x\n",
        "print(y)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "80yui3PudI8l",
        "colab_type": "text"
      },
      "source": [
        "\n",
        "Évidemment, l'utilisation de ces Tensors super sophistiqués (et puissants!) Est importante, mais vous oblige également à avoir les données sur votre machine locale. C'est là que commence notre voyage."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "n_MiPKtBdho-",
        "colab_type": "text"
      },
      "source": [
        "##Section 1.1 - Envoi de tenseurs à la machine de Bob\n",
        "\n",
        "Alors que normalement nous effectuerions la science des données / l'apprentissage en profondeur sur la machine qui contient les données, nous voulons maintenant effectuer ce type de calcul sur une autre machine. Plus précisément, nous ne pouvons plus simplement supposer que les données se trouvent sur notre machine locale.\n",
        "\n",
        "Ainsi, au lieu d'utiliser des tenseurs Torch, nous allons maintenant travailler avec des pointeurs vers des tenseurs. Permettez-moi de vous montrer ce que je veux dire. Créons d'abord une machine à \"faire semblant\" appartenant à une personne \"à faire semblant\" - nous l'appellerons Bob.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dxewoTjPd-xO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob = sy.VirtualWorker(hook, id=\"bob\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_088HkvWeEJN",
        "colab_type": "text"
      },
      "source": [
        "Disons que la machine de Bob est sur une autre planète - peut-être sur Mars! Mais, pour le moment, la machine est vide. Créons des données pour que nous puissions les envoyer à Bob et en apprendre davantage sur les pointeurs!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I1szwjNKeLjz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = torch.tensor([1,2,3,4,5])\n",
        "y = torch.tensor([1,1,1,1,1])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2ZxLIkKBeRyn",
        "colab_type": "text"
      },
      "source": [
        "Et maintenant - envoyons nos tensors à Bob !!\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bihG1mXheLEl",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr = x.send(bob)\n",
        "y_ptr = y.send(bob)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FIIV7FTDeeGm",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Mbbz94Qpefqq",
        "colab_type": "text"
      },
      "source": [
        "BOOM! Maintenant, Bob a deux tensors! Vous ne me croyez pas? Jetez un œil par vous-même!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "pLyge2s_en5A",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob._objects"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "oxjPYLYjesvU",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z = x_ptr + x_ptr"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4VrebTAletTo",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bWDjOLtbexT3",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob._objects"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3fam_d5NezL3",
        "colab_type": "text"
      },
      "source": [
        "Maintenant remarquez quelque chose. Lorsque nous avons appelé `x.send (bob)`, il a renvoyé un nouvel objet que nous avons appelé `x_ptr`. Ceci est notre premier pointeur sur un tensor. Les pointeurs vers les tenseurs ne contiennent PAS réellement les données eux-mêmes. Au lieu de cela, ils contiennent simplement des métadonnées sur un tensor (avec des données) stockées sur une autre machine. Le but de ces tenseurs est de nous donner une API intuitive pour dire à l'autre machine de calculer les fonctions utilisant ce tensor. Jetons un coup d'œil aux métadonnées que contiennent les pointeurs."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DRsgoDOafHZa",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sbRiEzVNfKME",
        "colab_type": "text"
      },
      "source": [
        "Découvrez ces métadonnées!\n",
        "\n",
        "Il existe deux principaux attributs spécifiques aux pointeurs:\n",
        "\n",
        "* x_ptr.location: bob, l'emplacement, une référence à l'emplacement vers lequel pointe le pointeur\n",
        "* x_ptr.id_at_location: <entier aléatoire>, l'id où le tensor est stocké à l'emplacement\n",
        "\n",
        "Ils sont imprimés au format `<id_at_location> @ <location>`\n",
        "\n",
        "Il existe également d'autres attributs plus génériques:\n",
        "\n",
        "* x_ptr.id: <entier aléatoire>, l'id de notre tensor de pointeur, il a été alloué de façon aléatoire\n",
        "* x_ptr.owner: \"moi\", l'ouvrier qui possède le tensor de pointeur, ici c'est l'ouvrier local, nommé \"moi\""
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "igPrYF73fk3a",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr.location"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6Bc0gZBdfubr",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OiBTuiQAfuXa",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob == x_ptr.location"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fBW1_7_qfuU1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr.id_at_location"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "l_ajVOvQfuSf",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr.owner"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CUKtgNeDf14b",
        "colab_type": "text"
      },
      "source": [
        "Vous vous demandez peut-être pourquoi le travailleur local qui possède le pointeur est également un VirtualWorker, même si nous ne l'avons pas créé. Fait amusant, tout comme nous avions un objet VirtualWorker pour Bob, nous (par défaut) en avons toujours un pour nous également. Ce travailleur est automatiquement créé lorsque nous avons appelé `hook = sy.TorchHook()` et vous n'avez donc généralement pas à le créer vous-même.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jQIIjokyfuQh",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "me = sy.local_worker\n",
        "me"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tCxhFJtGgJUo",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "me == x_ptr.owner"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PBPNo609gMKV",
        "colab_type": "text"
      },
      "source": [
        "Et enfin, tout comme nous pouvons appeler `.send()` sur un tenseur, nous pouvons appeler `.get()` sur un pointeur vers un tenseur pour le récupérer !!!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JA5EUlw1gUv4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "KIzNRgEAgXbD",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x_ptr.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Lm8kZku9gXYN",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "y_ptr"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OvQRaR8mgXWJ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "y_ptr.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "KCACebOygXSv",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t9UQSbNqgXMD",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "bob._objects"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "QPBMDjc-ggG6",
        "colab_type": "text"
      },
      "source": [
        "Et comme vous pouvez le voir ... Bob n'a plus les tensors !!! Ils sont revenus sur notre machine!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SHaGWLQngoia",
        "colab_type": "text"
      },
      "source": [
        "##Section 1.2 - Utilisation des pointeurs tensors\n",
        "\n",
        "Donc, envoyer et recevoir des tensors de Bob est génial, mais ce n'est pas du Deep Learning! Nous voulons pouvoir effectuer des opérations de tensors sur des tensors distants. Heureusement, les pointeurs tensors rendent cela assez facile! Vous pouvez simplement utiliser des pointeurs comme vous le feriez avec des tensors normaux!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Z17dJFwggnoL",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = torch.tensor([1,2,3,4,5]).send(bob)\n",
        "y = torch.tensor([1,1,1,1,1]).send(bob)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4QGSLY0phBV9",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z = x + y"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XJFoX0s8hBOU",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TevtiuRwhTXq",
        "colab_type": "text"
      },
      "source": [
        "Et voilà!\n",
        "\n",
        "Dans les coulisses, quelque chose de très puissant s'est produit. Au lieu que x et y calculent un ajout localement, une commande a été sérialisée et envoyée à Bob, qui a effectué le calcul, créé un tensor z, puis nous a renvoyé le pointeur z!\n",
        "\n",
        "Si nous appelons `.get()` sur le pointeur, nous recevrons alors le résultat sur notre machine!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yXlsU3ZZhY9S",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Y0ZwidHihed5",
        "colab_type": "text"
      },
      "source": [
        "##Fonctions de Torch \n",
        "\n",
        "Cette API a été étendue à toutes les opérations de Torch !!!"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "euvyXN-Ghsxu",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dKOpEfMchvIB",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "y"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SmxiPk4Dhv11",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z = torch.add(x,y)\n",
        "z"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZbAuKm5chykm",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pau3NaaAhzoh",
        "colab_type": "text"
      },
      "source": [
        "##Variables(comprenant backpropagation!)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AHm1hxcJiBLH",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = torch.tensor([1,2,3,4,5.], requires_grad=True).send(bob)\n",
        "y = torch.tensor([1,1,1,1,1.], requires_grad=True).send(bob)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "GuBxyM0fiHw7",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z = (x + y).sum()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qq5P9fWaiHt-",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "z.backward()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "13P3j9sviHrA",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = x.get()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4SHb957XiHol",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4GiDnPZkiHl_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x.grad"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZCJKvPuAiQUI",
        "colab_type": "text"
      },
      "source": [
        "Donc, comme vous pouvez le voir, l'API est vraiment assez flexible et capable d'effectuer presque toutes les opérations que vous effectuez normalement dans Torch sur des données distantes. Cela jette les bases de nos protocoles plus avancés de préservation de la confidentialité tels que Federated Learning, Secure Multi-Party Computation, and Differential Privacy !"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5MxTMX_Yi6JQ",
        "colab_type": "text"
      },
      "source": [
        "##Toutes nos félicitations!!! - Il est temps de rejoindre la communauté!\n",
        "Félicitations pour avoir terminé ce didacticiel pour ordinateur portable! Si cela vous a plu et que vous souhaitez rejoindre le mouvement vers la préservation de la vie privée, la propriété décentralisée de l'AI et la chaîne d'approvisionnement de l'AI (données), vous pouvez le faire de la manière suivante!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eRaKrfYbjIZe",
        "colab_type": "text"
      },
      "source": [
        "##Star PySyft sur GitHub\n",
        "Le moyen le plus simple d'aider notre communauté est simplement de mettre en vedette les dépôts GitHub! Cela permet de faire connaître les outils sympas que nous construisons.\n",
        "\n",
        "* [Star PySyft](https://github.com/OpenMined/PySyft)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_4ZBSRfjjITc",
        "colab_type": "text"
      },
      "source": [
        "##Joindrez notre Slack!\n",
        "La meilleure façon de vous tenir au courant des dernières avancées est de rejoindre notre communauté! Vous pouvez le faire en remplissant le formulaire à http://slack.openmined.org"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dJ5QeioOjIQQ",
        "colab_type": "text"
      },
      "source": [
        "##Joindrez un projet de code!\n",
        "La meilleure façon de contribuer à notre communauté est de devenir un contributeur de code! À tout moment, vous pouvez accéder à la page Problèmes de PySyft GitHub et filtrer pour \"Projects\". Cela vous montrera tous les billets de haut niveau donnant un aperçu des projets que vous pouvez rejoindre! Si vous ne souhaitez pas rejoindre un projet, mais que vous souhaitez faire un peu de codage, vous pouvez également rechercher d'autres mini-projets \"uniques\" en recherchant les problèmes GitHub marqués \"good first issue\".\n",
        "* [PySyft Project](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
        "* [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JLFhZLQ2ke1k",
        "colab_type": "text"
      },
      "source": [
        "##Faire un don\n",
        "Si vous n'avez pas le temps de contribuer à notre base de code, mais souhaitez tout de même apporter votre soutien, vous pouvez également devenir Backer sur notre Open Collective. Tous les dons vont à notre hébergement Web et à d'autres dépenses de la communauté telles que les hackathons et les rencontres!\n",
        "\n",
        "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "vxa_w4NAinUL",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}